home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / µSim 1.1 / source / Assembler.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-26  |  11.2 KB  |  419 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993-1997 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11.  
  12. #include    <ctype.h>
  13. #pragma fourbyteints on
  14. #include    <stdlib.h>
  15. #pragma fourbyteints reset
  16.  
  17. #include    <Limits.h>
  18.  
  19. #include    "UtilsSys7.h"
  20. #include    "Conversions.h"
  21. #include    "MovableModal.h"
  22. #include    "SimResIDs.h"
  23.  
  24. #include    "Assembler.h"
  25. #include    "Compares.h"
  26. #include    "Disasm.h"
  27. #include    "DoEditDialog.h"
  28. #include    "DoMenu.h"
  29. #include    "Dump.h"
  30. #include    "Globals.h"
  31. #include    "Main.h"
  32. #include    "Microprogram_Ed.h"
  33. #include    "SimUtils.h"
  34. #include    "AEHandlers.h"
  35.  
  36. #if defined(FabSystem7orlater)
  37.  
  38. #pragma fourbyteints on
  39. #pragma segment Rare
  40.  
  41. enum {
  42. kOPCMAXLEN = 4,
  43. kGROW_SYMTAB = 50,
  44. kGROW_OBJTAB = 150,
  45. kBITS_12 = 0x0FFF,
  46. kBITS_11 = 0x07FF,
  47. kBITS_8 = 0x00FF
  48. };
  49.  
  50. struct symtable {
  51.     StringHandle    symb;
  52.     long    value;
  53.     };
  54.  
  55. typedef struct symtable symtable;
  56. typedef symtable *symtablePtr;
  57. typedef symtablePtr *symtableHandle;
  58.  
  59. #if defined(powerc) || defined (__powerc)
  60. #pragma options align=mac68k
  61. #endif
  62. struct objtable {
  63.     long    operand;
  64.     Byte    length;
  65.     Byte    classe;
  66.     unsigned short    opcod;
  67.     Boolean    isSymbol;
  68.     Boolean    reserved;
  69.     };
  70. #if defined(powerc) || defined(__powerc)
  71. #pragma options align=reset
  72. #endif
  73.  
  74. typedef struct objtable objtable;
  75. typedef objtable *objtablePtr;
  76. typedef objtablePtr *objtableHandle;
  77.  
  78. static OSErr OnePassAsm(Handle fileBuffer);
  79. static long CountReturns(Handle fileBuffer, char *lastpos);
  80. static Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr theD);
  81.  
  82.  
  83. /* myAsmFile: reads theFile to be assembled into memory */
  84.  
  85. OSErr myAsmFile(FSSpec *theFile)
  86. {
  87. ParamBlockRec    myPB;
  88. EventRecord    dummyEv;
  89. register Handle    tempBuffer;
  90. unsigned long    fileSize;
  91. short    asmFileRefN;
  92. register OSErr    err;
  93.  
  94. SetCursor(*gWatchHandle);
  95. if ((err = FSpOpenDFCompat(theFile, fsRdPerm, &asmFileRefN)) == noErr) {
  96.     if ((err = GetEOF(asmFileRefN, (long *)&fileSize)) == noErr) {
  97.         if (tempBuffer = NewHandleGeneral(fileSize)) {
  98.             myPB.ioParam.ioCompletion = nil;
  99.             myPB.ioParam.ioRefNum = asmFileRefN;
  100.             HLock(tempBuffer);
  101.             myPB.ioParam.ioBuffer = *tempBuffer;
  102.             myPB.ioParam.ioReqCount = fileSize;
  103.             myPB.ioParam.ioPosMode = fsFromStart | kNoCacheMask;
  104.             myPB.ioParam.ioPosOffset = 0L;
  105.             (void)PBReadAsync(&myPB);
  106.             while (myPB.ioParam.ioResult > 0) {
  107.                 SystemTask();
  108.                 (void)EventAvail(everyEvent, &dummyEv);
  109.                 }
  110.             HUnlock(tempBuffer);
  111.             if ((err = myPB.ioParam.ioResult) == noErr) {
  112.                 err = OnePassAsm(tempBuffer);
  113.                 InvalDump();
  114.                 InvalDisasm();
  115.                 }
  116.             DisposeHandle(tempBuffer);
  117.             }
  118.         else err = MemError();
  119.         }
  120.     (void)FSClose(asmFileRefN);
  121.     }
  122. InitCursor();
  123. return(err);
  124. }
  125.  
  126. /* OnePassAsm: assembles the file passed in the buffer */
  127.  
  128. static OSErr OnePassAsm(Handle fileBuffer)
  129. {
  130. Str255    tempS;
  131. Handle    SortedOpcodeTable;
  132. symtableHandle    SymbolTable;
  133. objtableHandle    ObjTable;
  134. Handle    tempH;
  135. Ptr    myEOF;
  136. long    ILC;
  137. ROpcodePtr    found;
  138. symtablePtr    foundsym;
  139. Size    ObjTabOffset, SymTabOffset, tmpSize;
  140. int    numinstr;
  141. short    build;
  142. OSErr    err;
  143. register Byte    i;
  144. register char *ex = nil;
  145. register char *copy;
  146.  
  147. err = noErr;
  148. ILC = (long)gILCBase << 1;
  149. DetachResource(SortedOpcodeTable = Get1Resource(krInstructions, kOPCODES));
  150. HNoPurge(SortedOpcodeTable);
  151. qsort((*SortedOpcodeTable) + 2, numinstr = (*(unsigned short *)*SortedOpcodeTable) + 1,
  152.     sizeof(ROpcode), compareMnem);
  153.  
  154. /* init symbol & object table */
  155. if ((SymbolTable = (symtableHandle)NewHandleGeneral(sizeof(symtable)*kGROW_SYMTAB))) {
  156.     if ((ObjTable = (objtableHandle)NewHandleGeneral(sizeof(objtable)*kGROW_OBJTAB))) {
  157.         SymTabOffset = 0L;
  158.         ObjTabOffset = 0L;
  159.         HLock(fileBuffer);
  160.         ex = *fileBuffer;
  161.         myEOF = (Ptr)((Size)ex + InlineGetHandleSize(fileBuffer));
  162.         do {
  163.             if (*ex == 13)
  164.                 ex++;
  165.             else {
  166.                 if (ispunct(*ex))
  167.                     while (*ex++ != 13)
  168.                         ;
  169.                 else {
  170.                     if (isspace(*ex) == 0) {
  171.                         copy = (char *)&tempS[1];
  172.                         i = 0;
  173.                         do {
  174.                             *copy++ = *ex++;
  175.                             i++;
  176.                             }
  177.                         while (isspace(*ex) == 0);
  178.                         tempS[0] = i;
  179.                         /* add to symbol table */
  180.                         if (SymTabOffset >= (tmpSize = InlineGetHandleSize((Handle)SymbolTable)))
  181.                             SetHandleSize((Handle)SymbolTable, tmpSize + sizeof(symtable)*kGROW_SYMTAB);
  182.                         tempH = (Handle)NewString(tempS);
  183.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->symb = (StringHandle)tempH;
  184.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->value = ILC;
  185.                         SymTabOffset += sizeof(symtable);
  186.                         }
  187.                     if (*ex == 13)
  188.                         ex++;
  189.                     else {
  190.                         while (isspace(*ex++))
  191.                             ;
  192.                         --ex;
  193.                         copy = (char *)&tempS;
  194.                         i = 0;
  195.                         do {
  196.                             *copy++ = *ex++;
  197.                             i++;
  198.                             }
  199.                         while (isspace(*ex) == 0);
  200.                         if (i > kOPCMAXLEN) {
  201.                             err = kasmErrInvalidOpcode;
  202.                             break;
  203.                             }
  204.                         else {
  205.                             while (i < kOPCMAXLEN) {
  206.                                 i++;
  207.                                 *copy++ = ' ';
  208.                                 }
  209.                             if (ObjTabOffset >= (tmpSize = InlineGetHandleSize((Handle)ObjTable)))
  210.                                 SetHandleSize((Handle)ObjTable, tmpSize + sizeof(objtable)*kGROW_OBJTAB);
  211.                             found = (ROpcodePtr)bsearch(&tempS, (*SortedOpcodeTable)+2,
  212.                                     numinstr, sizeof(ROpcode), compareMnem);
  213.                             if (found == nil) {
  214.                                 err = kasmErrInvalidOpcode;
  215.                                 break;
  216.                                 }
  217.                             else {
  218.                                 *(long *)&((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->length = *(long *)(&found->length);
  219.                                 i = found->classe;
  220.                                 if (i == kCLASS_16_0) {
  221.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  222.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = 0L;
  223.                                     }
  224.                                 else {
  225.                                     while (isspace(*ex++))
  226.                                         ;
  227.                                     --ex;
  228.                                     if (*ex == '#') {
  229.                                         ++ex;
  230.                                         copy = (char *)&tempS[1];
  231.                                         i = 0;
  232.                                         do {
  233.                                             *copy++ = *ex++;
  234.                                             i++;
  235.                                             }
  236.                                         while (isspace(*ex) == 0);
  237.                                         tempS[0] = i;
  238.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  239.                                         StringToNum(tempS, &((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand);
  240.                                         }
  241.                                     else {
  242.                                         copy = (char *)&tempS[1];
  243.                                         i = 0;
  244.                                         do {
  245.                                             *copy++ = *ex++;
  246.                                             i++;
  247.                                             }
  248.                                         while (isspace(*ex) == 0);
  249.                                         tempS[0] = i;
  250.                                         tempH = (Handle)NewString(tempS);
  251.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = true;
  252.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = (long)tempH;
  253.                                         }
  254.                                     }
  255.                                 ObjTabOffset += sizeof(objtable);
  256.                                 }
  257.                             while (*ex++ != 13)
  258.                                 ;
  259.                             ILC += found->length;
  260.                             }
  261.                         }
  262.                     }
  263.                 }
  264.             }
  265.         while (ex < myEOF);
  266.         HUnlock(fileBuffer);
  267.         if (err == noErr)
  268.             /* check for ILC out of bounds */
  269.             if (ILC > kSIZE_RAM - 4096)
  270.                 err = kasmErrPotHeapDamage;
  271.         if (err == noErr) {
  272.             ILC = (long)gILCBase << 1;
  273.             qsort(*SymbolTable, SymTabOffset / sizeof(symtable), sizeof(symtable), cmpsymb);
  274.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable)) {
  275.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol) {
  276.                     foundsym = (symtablePtr)
  277.                         bsearch(&((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand,
  278.                         *SymbolTable, SymTabOffset / sizeof(symtable),
  279.                         sizeof(symtable), cmpsymb);
  280.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol = false;
  281.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  282.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand =
  283.                             (foundsym ? (((objtablePtr)(*(Handle)ObjTable + tmpSize))->classe >= kCLASS_16_16_REL
  284.                             ? (foundsym->value - ILC - ((objtablePtr)(*(Handle)ObjTable + tmpSize))->length) >> 1
  285.                             : foundsym->value) : (err = kasmErrSymbolNotDef, 0L));
  286.                     }
  287.                 switch (((objtablePtr)(*(Handle)ObjTable + tmpSize))->classe) {
  288.                     case kCLASS_4_12:
  289.                     case kCLASS_4_12_REL:
  290.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  291.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_12));
  292.                         *(short *)(gMMemory + ILC) = build;
  293.                         ILC += 2;
  294.                         break;
  295.                     case kCLASS_5_11:
  296.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  297.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_11));
  298.                         *(short *)(gMMemory + ILC) = build;
  299.                         ILC += 2;
  300.                         break;
  301.                     case kCLASS_8_8:
  302.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  303.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_8));
  304.                         *(short *)(gMMemory + ILC) = build;
  305.                         ILC += 2;
  306.                         break;
  307.                     case kCLASS_16_0:
  308.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  309.                         ILC += 2;
  310.                         break;
  311.                     case kCLASS_16_16:
  312.                     case kCLASS_16_16_REL:
  313.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  314.                         ILC += 2;
  315.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand;
  316.                         ILC += 2;
  317.                         break;
  318.                     }
  319.                 }
  320.             }
  321.         if ((err != noErr) && (err != kasmErrSymbolNotDef))
  322.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable))
  323.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol)
  324.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  325.         for(tmpSize = 0; tmpSize < SymTabOffset; tmpSize += sizeof(symtable))
  326.             DisposeHandle((Handle)((symtablePtr)(*(Handle)SymbolTable + tmpSize))->symb);
  327.         DisposeHandle((Handle)ObjTable);
  328.         }
  329.     else err = MemError();
  330.     DisposeHandle((Handle)SymbolTable);
  331.     }
  332. else err = MemError();
  333. DisposeHandle(SortedOpcodeTable);
  334. if (err > 0) {
  335.     InitCursor();
  336.     if (ex)
  337.         MyNumToString(1L + CountReturns(fileBuffer, ex), tempS);
  338.     else
  339.         *(short *)tempS = 0x013F;
  340.     ParamText(tempS, nil, nil, nil);
  341.     StopAlert_AE(kALRT_ASM + err, myStdFilterProcNoCancel, myIdleFunct);
  342.     err = 0;
  343.     }
  344. return err;
  345. }
  346.  
  347. static long CountReturns(Handle fileBuffer, char *lastpos)
  348. {
  349. register char *scanptr;
  350. register char *end = StripAddress(lastpos);
  351. register long    cnt = 0L;
  352.  
  353. for ( scanptr = StripAddress(*fileBuffer); scanptr <= end; )
  354.     if (*scanptr++ == 13)
  355.         ++cnt;
  356. return cnt;
  357. }
  358.  
  359.  
  360. enum {
  361. kItemAsmDestLoc = 3
  362. };
  363.  
  364. void DoAsmPrefsDialog(void)
  365. {
  366. Str255    AsmDestStr;
  367.  
  368. dialogItems    things[] = {{ ok, 0, 1L },
  369.                         { cancel, 0, 0L },
  370.                         { kItemAsmDestLoc, 0, 0L },
  371.                         { 0, 0, 0L}
  372.                         };
  373.  
  374. things[kItemAsmDestLoc-1].refCon = (long)&AsmDestStr;
  375.  
  376. ShortToHexString(gILCBase, AsmDestStr);
  377.  
  378. if (HandleMovableModalDialog(things, gPrefs.remembWind ? &gPrefs.asmPrefsTL : nil, nil, nil, nil, nil, nil,
  379.     AdjustMenus,
  380.     Handle_My_Menu,
  381.     DomyKeyEvent,
  382.     AsmPrefsPreProcessKey,
  383.     nil,
  384.     DoUpdate,
  385.     DoActivate,
  386.     DoHighLevelEvent,
  387.     DoOSEvent,
  388.     DoIdle,
  389.     ULONG_MAX,
  390.     kDLOG_ASMPREFS) == ok) {
  391.     HexStringToShort(AsmDestStr, (short *)&gILCBase);
  392.     }
  393. }
  394.  
  395. Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr /*theD*/)
  396. {
  397. //short    iHit;
  398. unsigned char    keypressed;
  399. Boolean    result = true;
  400.  
  401. keypressed = CHARFROMMESSAGE(thEv->message);
  402. if ((keypressed >= 'a') && (keypressed <= 'z')) {
  403.     keypressed -= 'a' - 'A';    /* cambiare! */
  404.     CHARFROMMESSAGE(thEv->message) = keypressed;
  405.     }
  406. //iHit = ((DialogPeek)theD)->editField + 1;
  407. if (keypressed >= 32 && ((thEv->modifiers & cmdKey) == 0)) {
  408.     result = ( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed,
  409.                             1L, 0L, 0L) >= 0L );
  410.     }
  411. return result;
  412. }
  413.  
  414.  
  415. #pragma fourbyteints reset
  416.  
  417. #endif
  418.  
  419.